home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / OLE / PPS / Root.php < prev   
PHP Script  |  2003-12-12  |  18KB  |  520 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Xavier Noguer <xnoguer@php.net>                              |
  17. // | Based on OLE::Storage_Lite by Kawai, Takanori                        |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Root.php,v 1.7 2003/12/12 21:10:10 xnoguer Exp $
  21.  
  22.  
  23. require_once ('OLE/PPS.php');
  24.  
  25. /**
  26. * Class for creating Root PPS's for OLE containers
  27. *
  28. * @author   Xavier Noguer <xnoguer@php.net>
  29. * @category Structures
  30. * @package  OLE
  31. */
  32. class OLE_PPS_Root extends OLE_PPS
  33. {
  34.     /**
  35.     * The temporary dir for storing the OLE file
  36.     * @var string
  37.     */
  38.     var $_tmp_dir;
  39.     
  40.     /**
  41.     * Constructor
  42.     *
  43.     * @access public
  44.     * @param integer $time_1st A timestamp
  45.     * @param integer $time_2nd A timestamp
  46.     */
  47.     function OLE_PPS_Root($time_1st, $time_2nd, $raChild)
  48.     {
  49.         $this->_tmp_dir = '';
  50.         $this->OLE_PPS(
  51.            null, 
  52.            OLE::Asc2Ucs('Root Entry'),
  53.            OLE_PPS_TYPE_ROOT,
  54.            null,
  55.            null,
  56.            null,
  57.            $time_1st,
  58.            $time_2nd,
  59.            null,
  60.            $raChild);
  61.     }
  62.  
  63.     /**
  64.     * Sets the temp dir used for storing the OLE file
  65.     *
  66.     * @access public
  67.     * @param string $dir The dir to be used as temp dir
  68.     * @return true if given dir is valid, false otherwise
  69.     */
  70.     function setTempDir($dir)
  71.     {
  72.         if (is_dir($dir)) {
  73.             $this->_tmp_dir = $dir;
  74.             return true;
  75.         }
  76.         return false;
  77.     }
  78.  
  79.     /**
  80.     * Method for saving the whole OLE container (including files).
  81.     * In fact, if called with an empty argument (or '-'), it saves to a
  82.     * temporary file and then outputs it's contents to stdout.
  83.     *
  84.     * @param string $filename The name of the file where to save the OLE container
  85.     * @access public
  86.     * @return mixed true on success, PEAR_Error on failure
  87.     */
  88.     function save($filename)
  89.     {
  90.         // Initial Setting for saving
  91.         $this->_BIG_BLOCK_SIZE  = pow(2,
  92.                       ((isset($this->_BIG_BLOCK_SIZE))? $this->_adjust2($this->_BIG_BLOCK_SIZE)  : 9));
  93.         $this->_SMALL_BLOCK_SIZE= pow(2, 
  94.                       ((isset($this->_SMALL_BLOCK_SIZE))?  $this->_adjust2($this->_SMALL_BLOCK_SIZE): 6));
  95.  
  96.         // Open temp file if we are sending output to stdout
  97.         if (($filename == '-') or ($filename == ''))
  98.         {
  99.             $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root");
  100.             $this->_FILEH_ = @fopen($this->_tmp_filename,"w+b");
  101.             if ($this->_FILEH_ == false) {
  102.                 return $this->raiseError("Can't create temporary file.");
  103.             }
  104.         }
  105.         else
  106.         {
  107.             $this->_FILEH_ = @fopen($filename, "wb");
  108.             if ($this->_FILEH_ == false) {
  109.                 return $this->raiseError("Can't open $filename. It may be in use or protected.");
  110.             }
  111.         }
  112.         // Make an array of PPS's (for Save)
  113.         $aList = array();
  114.         $this->_savePpsSetPnt($aList);
  115.         // calculate values for header
  116.         list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo);
  117.         // Save Header
  118.         $this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt);
  119.   
  120.         // Make Small Data string (write SBD)
  121.         $this->_data = $this->_makeSmallData($aList);
  122.   
  123.         // Write BB
  124.         $this->_saveBigData($iSBDcnt, $aList);
  125.         // Write PPS
  126.         $this->_savePps($aList);
  127.         // Write Big Block Depot and BDList and Adding Header informations
  128.         $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt);
  129.         // Close File, send it to stdout if necessary
  130.         if(($filename == '-') or ($filename == ''))
  131.         {
  132.             fseek($this->_FILEH_, 0);
  133.             fpassthru($this->_FILEH_);
  134.             @fclose($this->_FILEH_);
  135.             // Delete the temporary file.
  136.             @unlink($this->_tmp_filename);
  137.         }
  138.         else {
  139.             @fclose($this->_FILEH_);
  140.         }
  141.         return true;
  142.     }
  143.  
  144.     /**
  145.     * Calculate some numbers
  146.     *
  147.     * @access private
  148.     * @param array $raList Reference to an array of PPS's
  149.     * @return array The array of numbers
  150.     */
  151.     function _calcSize(&$raList) 
  152.     {
  153.         // Calculate Basic Setting
  154.         list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0);
  155.         $iSmallLen = 0;
  156.         $iSBcnt = 0;
  157.         for ($i = 0; $i < count($raList); $i++) {
  158.             if($raList[$i]->Type == OLE_PPS_TYPE_FILE) {
  159.                 $raList[$i]->Size = $raList[$i]->_DataLen();
  160.                 if($raList[$i]->Size < OLE_DATA_SIZE_SMALL) {
  161.                     $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
  162.                                   + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
  163.                 }
  164.                 else {
  165.                     $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
  166.                         (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
  167.                 }
  168.             }
  169.         }
  170.         $iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE;
  171.         $iSlCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
  172.         $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0);
  173.         $iBBcnt +=  (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) +
  174.                       (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0));
  175.         $iCnt = count($raList);
  176.         $iBdCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
  177.         $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0));
  178.    
  179.         return array($iSBDcnt, $iBBcnt, $iPPScnt);
  180.     }
  181.  
  182.     /**
  183.     * Helper function for caculating a magic value for block sizes
  184.     *
  185.     * @access private
  186.     * @param integer $i2 The argument
  187.     * @see save()
  188.     * @return integer
  189.     */
  190.     function _adjust2($i2)
  191.     {
  192.         $iWk = log($i2)/log(2);
  193.         return ($iWk > floor($iWk))? floor($iWk)+1:$iWk;
  194.     }
  195.  
  196.     /**
  197.     * Save OLE header
  198.     *
  199.     * @access private
  200.     * @param integer $iSBDcnt
  201.     * @param integer $iBBcnt
  202.     * @param integer $iPPScnt
  203.     */
  204.     function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt)
  205.     {
  206.         $FILE = $this->_FILEH_;
  207.   
  208.         // Calculate Basic Setting
  209.         $iBlCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
  210.         $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
  211.   
  212.         $iBdExL = 0;
  213.         $iAll = $iBBcnt + $iPPScnt + $iSBDcnt;
  214.         $iAllW = $iAll;
  215.         $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
  216.         $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
  217.   
  218.         // Calculate BD count
  219.         if ($iBdCnt >$i1stBdL)
  220.         {
  221.             while (1)
  222.             {
  223.                 $iBdExL++;
  224.                 $iAllW++;
  225.                 $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
  226.                 $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
  227.                 if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) {
  228.                     break;
  229.                 }
  230.             }
  231.         }
  232.   
  233.         // Save Header
  234.         fwrite($FILE,
  235.                   "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
  236.                   . "\x00\x00\x00\x00"
  237.                   . "\x00\x00\x00\x00"
  238.                   . "\x00\x00\x00\x00"
  239.                   . "\x00\x00\x00\x00"
  240.                   . pack("v", 0x3b)
  241.                   . pack("v", 0x03)
  242.                   . pack("v", -2)
  243.                   . pack("v", 9)
  244.                   . pack("v", 6)
  245.                   . pack("v", 0)
  246.                   . "\x00\x00\x00\x00"
  247.                   . "\x00\x00\x00\x00"
  248.                   . pack("V", $iBdCnt) 
  249.                   . pack("V", $iBBcnt+$iSBDcnt) //ROOT START
  250.                   . pack("V", 0)
  251.                   . pack("V", 0x1000)
  252.                   . pack("V", 0)                  //Small Block Depot
  253.                   . pack("V", 1)
  254.           );
  255.         // Extra BDList Start, Count
  256.         if ($iBdCnt < $i1stBdL)
  257.         {
  258.             fwrite($FILE,
  259.                       pack("V", -2).      // Extra BDList Start
  260.                       pack("V", 0)        // Extra BDList Count
  261.                   );
  262.         }
  263.         else
  264.         {
  265.             fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL));
  266.         }
  267.  
  268.         // BDList
  269.         for ($i=0; $i<$i1stBdL and $i < $iBdCnt; $i++) {
  270.             fwrite($FILE, pack("V", $iAll+$i));
  271.         }
  272.         if ($i < $i1stBdL)
  273.         {
  274.             for ($j = 0; $j < ($i1stBdL-$i); $j++) {
  275.                 fwrite($FILE, (pack("V", -1)));
  276.             }
  277.         }
  278.     }
  279.  
  280.     /**
  281.     * Saving big data (PPS's with data bigger than OLE_DATA_SIZE_SMALL)
  282.     *
  283.     * @access private
  284.     * @param integer $iStBlk
  285.     * @param array &$raList Reference to array of PPS's
  286.     */
  287.     function _saveBigData($iStBlk, &$raList)
  288.     {
  289.         $FILE = $this->_FILEH_;
  290.    
  291.         // cycle through PPS's
  292.         for ($i = 0; $i < count($raList); $i++)
  293.         {
  294.             if($raList[$i]->Type != OLE_PPS_TYPE_DIR)
  295.             {
  296.                 $raList[$i]->Size = $raList[$i]->_DataLen();
  297.                 if(($raList[$i]->Size >= OLE_DATA_SIZE_SMALL) or
  298.                     (($raList[$i]->Type == OLE_PPS_TYPE_ROOT) and isset($raList[$i]->_data)))
  299.                 {
  300.                     // Write Data
  301.                     if(isset($raList[$i]->_PPS_FILE))
  302.                     {
  303.                         $iLen = 0;
  304.                         fseek($raList[$i]->_PPS_FILE, 0); // To The Top
  305.                         while($sBuff = fread($raList[$i]->_PPS_FILE, 4096))
  306.                         {
  307.                             $iLen += strlen($sBuff);
  308.                             fwrite($FILE, $sBuff);
  309.                         }
  310.                     }
  311.                     else {
  312.                         fwrite($FILE, $raList[$i]->_data);
  313.                     }
  314.            
  315.                     if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)
  316.                     {
  317.                         for ($j = 0; $j < ($this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)); $j++) {
  318.                             fwrite($FILE, "\x00");
  319.                         }
  320.                     }
  321.                     // Set For PPS
  322.                     $raList[$i]->_StartBlock = $iStBlk;
  323.                     $iStBlk += 
  324.                             (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
  325.                                 (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
  326.                 }
  327.                 // Close file for each PPS, and unlink it
  328.                 if (isset($raList[$i]->_PPS_FILE))
  329.                 {
  330.                     @fclose($raList[$i]->_PPS_FILE);
  331.                     $raList[$i]->_PPS_FILE = null;
  332.                     @unlink($raList[$i]->_tmp_filename);
  333.                 }
  334.             }
  335.         }
  336.     }
  337.  
  338.     /**
  339.     * get small data (PPS's with data smaller than OLE_DATA_SIZE_SMALL)
  340.     *
  341.     * @access private
  342.     * @param array &$raList Reference to array of PPS's
  343.     */
  344.     function _makeSmallData(&$raList)
  345.     {
  346.         $sRes = '';
  347.         $FILE = $this->_FILEH_;
  348.         $iSmBlk = 0;
  349.    
  350.         for ($i = 0; $i < count($raList); $i++)
  351.         {
  352.             // Make SBD, small data string
  353.             if ($raList[$i]->Type == OLE_PPS_TYPE_FILE)
  354.             {
  355.                 if ($raList[$i]->Size <= 0) {
  356.                     continue;
  357.                 }
  358.                 if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL)
  359.                 {
  360.                     $iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
  361.                                   + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
  362.                     // Add to SBD
  363.                     for ($j = 0; $j < ($iSmbCnt-1); $j++) {
  364.                         fwrite($FILE, pack("V", $j+$iSmBlk+1));
  365.                     }
  366.                     fwrite($FILE, pack("V", -2));
  367.                    
  368.                     // Add to Data String(this will be written for RootEntry)
  369.                     if ($raList[$i]->_PPS_FILE)
  370.                     {
  371.                         fseek($raList[$i]->_PPS_FILE, 0); // To The Top
  372.                         while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
  373.                             $sRes .= $sBuff;
  374.                         }
  375.                     }
  376.                     else {
  377.                         $sRes .= $raList[$i]->_data;
  378.                     }
  379.                     if($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)
  380.                     {
  381.                         for ($j = 0; $j < ($this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); $j++) {
  382.                             $sRes .= "\x00";
  383.                         }
  384.                     }
  385.                     // Set for PPS
  386.                     $raList[$i]->_StartBlock = $iSmBlk;
  387.                     $iSmBlk += $iSmbCnt;
  388.                 }
  389.             }
  390.         }
  391.         $iSbCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE);
  392.         if($iSmBlk % $iSbCnt)
  393.         {
  394.             for ($i = 0; $i < ($iSbCnt - ($iSmBlk % $iSbCnt)); $i++) {
  395.                 fwrite($FILE, pack("V", -1));
  396.             }
  397.         }
  398.         return $sRes;
  399.     }
  400.  
  401.     /**
  402.     * Saves all the PPS's WKs
  403.     *
  404.     * @access private
  405.     * @param array $raList Reference to an array with all PPS's
  406.     */
  407.     function _savePps(&$raList) 
  408.     {
  409.         // Save each PPS WK
  410.         for ($i = 0; $i < count($raList); $i++) {
  411.             fwrite($this->_FILEH_, $raList[$i]->_getPpsWk());
  412.         }
  413.         // Adjust for Block
  414.         $iCnt = count($raList);
  415.         $iBCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE;
  416.         if ($iCnt % $iBCnt)
  417.         {
  418.             for ($i = 0; $i < (($iBCnt - ($iCnt % $iBCnt)) * OLE_PPS_SIZE); $i++) {
  419.                 fwrite($this->_FILEH_, "\x00");
  420.             }
  421.         }
  422.     }
  423.  
  424.     /**
  425.     * Saving Big Block Depot
  426.     *
  427.     * @access private
  428.     * @param integer $iSbdSize
  429.     * @param integer $iBsize
  430.     * @param integer $iPpsCnt
  431.     */
  432.     function _saveBbd($iSbdSize, $iBsize, $iPpsCnt) 
  433.     {
  434.         $FILE = $this->_FILEH_;
  435.         // Calculate Basic Setting
  436.         $iBbCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE;
  437.         $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE;
  438.       
  439.         $iBdExL = 0;
  440.         $iAll = $iBsize + $iPpsCnt + $iSbdSize;
  441.         $iAllW = $iAll;
  442.         $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
  443.         $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
  444.         // Calculate BD count
  445.         if ($iBdCnt >$i1stBdL)
  446.         {
  447.             while (1)
  448.             {
  449.                 $iBdExL++;
  450.                 $iAllW++;
  451.                 $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
  452.                 $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
  453.                 if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) {
  454.                     break;
  455.                 }
  456.             }
  457.         }
  458.       
  459.         // Making BD
  460.         // Set for SBD
  461.         if ($iSbdSize > 0)
  462.         {
  463.             for ($i = 0; $i<($iSbdSize-1); $i++) {
  464.                 fwrite($FILE, pack("V", $i+1));
  465.             }
  466.             fwrite($FILE, pack("V", -2));
  467.         }
  468.         // Set for B
  469.         for ($i = 0; $i<($iBsize-1); $i++) {
  470.             fwrite($FILE, pack("V", $i+$iSbdSize+1));
  471.         }
  472.         fwrite($FILE, pack("V", -2));
  473.       
  474.         // Set for PPS
  475.         for ($i = 0; $i<($iPpsCnt-1); $i++) {
  476.             fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1));
  477.         }
  478.         fwrite($FILE, pack("V", -2));
  479.         // Set for BBD itself ( 0xFFFFFFFD : BBD)
  480.         for ($i=0; $i<$iBdCnt;$i++) {
  481.             fwrite($FILE, pack("V", 0xFFFFFFFD));
  482.         }
  483.         // Set for ExtraBDList
  484.         for ($i=0; $i<$iBdExL;$i++) {
  485.             fwrite($FILE, pack("V", 0xFFFFFFFC));
  486.         }
  487.         // Adjust for Block
  488.         if (($iAllW + $iBdCnt) % $iBbCnt)
  489.         {
  490.             for ($i = 0; $i < ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); $i++) {
  491.                 fwrite($FILE, pack("V", -1));
  492.             }
  493.         }
  494.         // Extra BDList
  495.         if ($iBdCnt > $i1stBdL)
  496.         {
  497.             $iN=0;
  498.             $iNb=0;
  499.             for ($i=$i1stBdL;$i<$iBdCnt; $i++, $iN++)
  500.             {
  501.                 if ($iN>=($iBbCnt-1))
  502.                 {
  503.                     $iN = 0;
  504.                     $iNb++;
  505.                     fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb));
  506.                 }
  507.                 fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i));
  508.             }
  509.             if (($iBdCnt-$i1stBdL) % ($iBbCnt-1))
  510.             {
  511.                 for ($i = 0; $i < (($iBbCnt-1) - (($iBdCnt-$i1stBdL) % ($iBbCnt-1))); $i++) {
  512.                     fwrite($FILE, pack("V", -1)); 
  513.                 }
  514.             }
  515.             fwrite($FILE, pack("V", -2));
  516.         }
  517.     }
  518. }
  519. ?>
  520.